<template>
	<view class="peng-lazy-tree">
		<view class="peng-tree-mask" :class="{'show':diaLog?showTree:'false'}" v-if="diaLog" @tap="_maskClick"></view>
		<view class="peng-tree-cnt" :class="{'show':diaLog?showTree:'false'}" :style="{top:diaLog?'600rpx':'0rpx'}">
			<view class="peng-tree-bar" style="padding-top:20rpx;padding-bottom: 20rpx;" v-if="diaLog">
				<view class="peng-tree-bar-cancel" :style="{'color':cancelColor}" hover-class="hover-c" @tap="_hide">关闭
				</view>
				<view class="midInput" v-if="showSearch">
					<!-- 由于数据量大，不适用于前端检索 -->
					<u-search :showAction="false" shape="round" :clearabled="true" v-model="InputEvent"
						v-if="fontSearch" @change="filterOp" :placeholder="'请输入'+title"></u-search>
					<u-search :showAction="false" shape="round" :clearabled="true" v-model="InputEvent" v-else
						@search="endSearch" @clear="clearMethods" confirmType="search" :placeholder="'请输入'+title">
					</u-search>
				</view>
				<view class="peng-tree-bar-title" v-else :style="{'color':titleColor}">{{title}}</view>
				<view class="peng-tree-bar-confirm" :style="{'color':confirmColor}" hover-class="hover-c"
					@tap="_confirm">确定</view>
			</view>
			<view class="peng-tree-bar-nodiaLog" v-else>
				<!-- 无弹窗显示检索  服务端检索 -->
				<view class="nodiaLog-search">
					<u-search :showAction="false" shape="round" :clearabled="true" v-model="InputEvent"
						:search-icon-color="confirmColor" @search="endSearch" @clear="clearMethods" confirmType="search"
						:placeholder="'请输入'+title"></u-search>
				</view>
			</view>
			<view class="peng-tree-view" :style="{top:diaLog?'90rpx':'80rpx',paddingTop:diaLog?'20rpx':'10rpx'}">
				<scroll-view class="peng-tree-view-sc" :scroll-y="true">
					<block v-for="(item, index) in treeList" :key="index"
						v-if="item.isPickerShow == true || item.isPickerShow == undefined">
						<view class="peng-tree-item" :style="[{
							paddingLeft: item.rank*15 + 'px',
							zIndex: item.rank*-1 +50
						}]" :class="{
							show: item.show,
							last: item.lastRank,
							showchild: item.showChild,
						}">
							<view class="peng-tree-label" @tap.stop="_treeItemTap(item, index)">
								<image class="peng-tree-system-icon" :src="deveiceIcon"></image>
								<!-- <text :style="{color:item.showChild ? activeColor : '' }">{{item.name}}</text> -->
								<text :style="{color:item.Highlight ? activeColor : '' }">{{item.name}}</text>

								<image class="peng-tree-icon"
									:src="item.lastRank ? lastIcon : item.showChild ? currentIcon : defaultIcon">
								</image>
							</view>
							<!-- 是否有选择按钮 -->
							<view class="peng-tree-check" @tap.stop="_treeItemSelect(item, index)"
								v-if="selectParent?true:item.lastRank &&isStartRadio">
								<view class="peng-tree-check-yes" v-if="item.checked" :class="{'radio':!multiple}"
									:style="{'border-color':confirmColor}">
									<view class="peng-tree-check-yes-b" :style="{'background-color':confirmColor}">
									</view>
								</view>
								<view class="peng-tree-check-no" v-else :class="{'radio':!multiple}"
									:style="{'border-color':confirmColor}"></view>
							</view>
						</view>
					</block>
				</scroll-view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props: {
			url: { // 接口地址
				type: String,
				default: ''
			},
			method: { // 接口请求的HTTP协议，默认为GIT
				type: String,
				default: 'GET'
			},
			header: { //接口传参
				type: Object,
				default: function() {
					return {}
				}
			},
			formData: { //接口传参
				type: Object,
				default: function() {
					return {}
				}
			},
			formUrl: { //url传参取数据传参
				// type: String,
				// default: 'id'
				type: Object,
				default: function() {
					return {}
				}
			},
			default: { //url传参取一级数据传参formUrl的默认值
				// type: String,
				// default: ''
				type: Object,
				default: function() {
					return {}
				}
			},

			success: {
				type: Array, //接口返回数据取值，最多支持两层
				default: function() {
					return []
				}
			},
			cancelColor: { // 取消按钮颜色
				type: String,
				default: '' // #757575
			},
			titleColor: { // 标题颜色
				type: String,
				default: '' // #757575
			},
			confirmColor: { // 确定按钮颜色
				type: String,
				default: '' // #007aff
			},
			title: { //标题
				type: String,
				default: ''
			},
			maskClick: { //点击遮罩层是否关闭
				type: Boolean,
				default: true
			},
			idKey: { //字段key值
				type: String,
				default: 'id'
			},
			fCompanyid: { //字段fCompanyid值
				type: String,
				default: 'fCompanyid'
			},
			nameKey: { //字段name值
				type: String,
				default: 'name'
			},
			Longname: { //字段nameFull值
				type: String,
				default: 'nameFull'
			},
			fLongids:{
				type: String,
				default: 'fLongids'
			},
			allKey: { //需要查询下一级的字段
				type: String,
				default: 'id'
			},

			selectParent: { //是否可以选父级
				type: Boolean,
				default: true
			},
			multiple: { // 是否可以多选
				type: Boolean,
				default: true
			},
			cascade: { // 是否级联选择
				type: Boolean,
				default: false
				// default: true
			},

			currentIcon: { // 展开时候的ic
				type: String,
				default: ''
			},
			defaultIcon: { // 折叠时候的ic
				type: String,
				default: ''
			},
			lastIcon: { // 没有子集的ic
				type: String,
				default: ''
			},
			deveiceIcon: { //树形结构标题图标
				type: String,
				default: ''
			},
			activeColor: { //激活的颜色
				type: String,
				default: ''
			},
			showSearch: { //判断是否显示检索框
				type: Boolean,
				default: true
			},
			isStartRadio: { //判断是否直接可以选中元素
				type: Boolean,
				default: false
			},
			childrenMark: { //判断是否末级字段标识
				type: String,
				default: ''
			},
			diaLog: { //判断组件是否为弹窗组件
				type: Boolean,
				default: true
			},
			fontSearch: { //判断是否前端检索
				type: Boolean,
				default: true
			},
			searchCondition: { //检索条件字段参数
				type: String,
				default: 'fLongname'
			}
		},
		data() {
			return {
				showTree: false,
				treeList: [],
				keyWord: '',
				InputEvent: '',
				Highlight: false
			}
		},
		methods: {
			//显示
			async _show() {
				let treeList = await this._interface(this.default);
				this.renderTreeList(treeList)
				this.showTree = true
			},
			renderTreeList(list) {
				list.data.forEach(item => {
					this.treeList.push({
						fCompanyid: item[this.fCompanyid],
						id: item[this.idKey],
						name: item[this.nameKey],
						nameFull: item[this.Longname],
						value: item[this.allKey],
						fLongids:item[this.fLongids],
						parentId: [], // 父级id数组
						sonarrId: [], //子级id数组
						rank: 0, // 层级
						showChild: false, //子级是否显示
						show: true, // 自身是否显示
						checked: false, //是否选中
						lastRank: false, //是否末级
						children: 0,
						Highlight: false, //是否高亮
					})
				})
			},
			// 点击
			async _treeItemTap(item, index) {
				this.treeList.map((item, i) => {
					if (i == index) {
						item.Highlight = true;
					} else {
						item.Highlight = false;
					}
				})


				if (item.lastRank === true) {
					//点击最后一级时触发事件
					this.treeList[index].checked = !this.treeList[index].checked
					this._fixMultiple(index)
					this.$emit('onlastData', item) //传递数据 点击的最后单行数据
					return;
				} else {
					this.$emit('onrowData', item) //传递数据 点击的那单行数据
				}
				//改变图标状态
				item.showChild = !item.showChild;
				//展示子集
				if (item.showChild) {
					//子集数据加载过则不在填充
					if (item.children > 0) {
						this.treeList.forEach((childItem, i) => {
							//隐藏所有子级
							if (childItem.parentId.includes(item.id) && item.parentId.length + 1 == childItem
								.parentId.length) {
								childItem.showChild = false;
								childItem.show = true
							}
						})
						return
					}
					let dataS = {
						fCompanyid: item.fCompanyid, //标段id 必填
						projectId: "", //项目id 必填
						parentId: item.id //父级id 第一级传-1  子级取上一级fId或fNodeid 必填
					}
					let treeList = await this._interface(dataS);
					item.children = treeList.data.length;
					treeList.data.forEach((ele) => {
						if (ele.childrenMark === this.childrenMark) { //判断是否有子级标识
							ele.lastRank = true
						} else {
							ele.lastRank = false
						}
					})
					//如果接口返回值为空认为是末级
					if (!treeList || treeList.length <= 0) {
						// item.lastRank = true  //没有数据子级的时候不显示数据
						/*处理数据格式  后续优化  不需要选中当前那行*/
						if (!this.isStartRadio) {
							this.treeList[index].checked = !this.treeList[index].checked
							this._fixMultiple(index)
						}
						return;
					}
					// 子元素插入的索引位置
					const nextIndex = this.treeList.findIndex(itemT => itemT.id === item.id)
					const newRank = item.rank + 1
					let parentId = []
					if (item.parentId.length > 0) {
						parentId = JSON.parse(JSON.stringify(item.parentId))
					}
					let sonarrId = []
					parentId.push(item.id)
					treeList.data.forEach(itemC => {
						const childObj = {
							fCompanyid: itemC[this.fCompanyid],
							id: itemC[this.idKey],
							name: itemC[this.nameKey],
							nameFull: itemC[this.Longname],
							value: itemC[this.allKey],
							fLongids:itemC[this.fLongids],
							parentId: parentId, // 父级id数组
							sonarrId: [], //子级id数组
							rank: item.rank + 1, // 层级
							showChild: false, //子级是否显示
							show: true, // 自身是否显示
							checked: this.cascade ? item.checked : false, //是否选中
							lastRank: itemC.lastRank, //是否末级
							children: 0,
							Highlight: false, //是否高亮
						}
						sonarrId.push(childObj.id)
						if (!this.treeList.some(itemT => itemT.id === itemC[this.idKey])) {
							this.treeList.splice(nextIndex + 1, 0, childObj)
						}
					})
					item.sonarrId = sonarrId
				} else {
					//隐藏子集
					this.treeList.forEach((childItem, i) => {
						//隐藏所有子级
						if (childItem.parentId.includes(item.id)) {
							childItem.showChild = false;
							childItem.show = false
						}
					})
				}
			},
			//隐藏、取消
			_hide() {
				this.showTree = false
				//解决关闭弹窗数据 依然存在的问题
				if (this.diaLog) {
					this.treeList = []
				}
			},
			//点击遮罩层
			_maskClick() {
				if (this.maskClick) {
					this._hide()
				}
			},
			_cancel() {
				this._hide()
				this.$emit("cancel", []);
			},
			//确定按钮
			_confirm() {
				// 处理所选数据
				
				let rt = []
				this.treeList.forEach((v, i) => { //主要用于判断多选操作，单次点击操作不需要判断checked
					if (this.treeList[i].checked) {
						console.log(858585,i,this.treeList[i].checked);
						rt.push({
							id: this.treeList[i].id,
							name: this.treeList[i].nameFull,
							parentId: this.treeList[i].parentId,
							fLongids:this.treeList[i].fLongids,
						})
					}
				})
				this._hide()
				console.log(rt);
				this.$emit("confirm", rt);
			},
			_treeItemSelect(item, index) {
				this.treeList[index].checked = !this.treeList[index].checked
				this._fixMultiple(index)
				//开启级联并且在多选状态下和父级可选的状态下
				if (this.cascade && this.multiple && this.selectParent) {
					//给子集孙集....同步选择状态
					this.treeList.forEach((childItem, i) => {
						if (childItem.parentId.includes(item.id)) {
							childItem.checked = item.checked
						}
					})
					//在子集选中之后同步父级状态
					if (item.rank > 0) {
						//如果是选中状态，选择性同步 父级状态
						if (item.checked) {
							let i = item.parentId.length - 1
							//倒序遍历父级数组
							for (i; i >= 0; i--) {
								//获取父级下标
								const nextIndex = this.treeList.findIndex(itemT => itemT.id === item.parentId[i])
								//从父级数据中取到所有同级id数组
								const obj = this.treeList[nextIndex].sonarrId
								//在所有同级选中的情况下type等于true
								let type = true
								//遍历同级id数组
								obj.forEach((childItem, i) => {
									//获取同级数据下标
									const ziIndex = this.treeList.findIndex(itemT => itemT.id === childItem)
									//判断同级是否选中
									if (!this.treeList[ziIndex].checked) {
										//只要有一个没选中type改为false
										type = false
									}
								})
								//遍历万所有同级之后，如果同级全都选中，则网父级同步状态
								if (type) {
									this.treeList[nextIndex].checked = true
								} else {
									//反之取消父级状态
									//（其实父级在现在的情况下本来就应该是false，加else纯属以防万一）
									this.treeList[nextIndex].checked = false
								}
							}
						} else {
							//子集取消状态，同时取消所有父级的选中状态
							item.parentId.forEach((childItem, i) => {
								const nextIndex = this.treeList.findIndex(itemT => itemT.id === childItem)
								this.treeList[nextIndex].checked = false
							})
						}
					}
				}
				// this._confirm()
			},
			// 处理单选多选
			_fixMultiple(index) {
				if (!this.multiple) {
					// 如果是单选
					this.treeList.forEach((v, i) => {
						if (i != index) {
							this.treeList[i].checked = false
						} else {
							this.treeList[i].checked = true
						}
					})
				}
			},
			_interface(key) {
				return new Promise((resolve, reject) => {
					let self = this;
					uni.request({
						// url: self.url + "?" + self.formUrl + "=" + key,
						url: self.url,
						method: self.method,
						// data: self.formData,
						// data: self.formUrl,
						data: key,
						header: self.header,
						success: (res) => {
							if (self.success.length <= 0) {
								resolve(res.data)
							} else if (self.success.length == 1) {
								resolve(res.data[self.success[0]])
							} else if (self.success.length == 2) {
								resolve(res.data[self.success[0]][self.success[1]])
							} else {
								this._hide()
								this.$emit("error", "接口数据层次太多，无法解析");
								return
							}
						},
						fail: (err) => {
							this._hide()
							this.$emit("error", err);
						}

					})
				})
			},
			//前端过滤检索
			filterOp(e) {
				let keyWord = e;
				this.keyWord = keyWord
				let oldArr = this.treeList;
				if (keyWord != "") {
					keyWord = keyWord.toLowerCase();
					const newArr = oldArr.map((item) => {
						item.children = 0
						if (item.name.toString().toLowerCase().indexOf(keyWord) > -1) {
							item['isPickerShow'] = true
						} else {
							item['isPickerShow'] = false
						}
						return item
					})
					this.treeList = newArr
				} else {
					const newArr = oldArr.map((item) => {
						delete item['isPickerShow']
						return item
					})
					this.treeList = newArr
				}
			},
			//后端检索
			async endSearch(e) {
				if (e !== undefined && e !== '') {
					let treeList = await this.get_Searchface(e)
					this.treeList = []
					this.renderTreeList(treeList)
				} else {
					this.clearMethods()
				}
			},
			//监听清空事件
			async clearMethods() {
				this.treeList = []
				this._show()
			},
			//获取检索条件
			get_Searchface(val) {
				return new Promise((resolve, reject) => {
					let self = this
					const searchField = self.searchCondition
					uni.request({
						// url: self.url + "?" + self.formUrl + "=" + '',
						url: self.url,
						method: self.method,
						data: {
							[searchField]: val
						}, //动态设置参数字段信息
						header: self.header,
						success: (res) => {
							self.formData.FCataName = null
							if (self.success.length <= 0) {
								resolve(res.data)
							} else if (self.success.length == 1) {
								resolve(res.data[self.success[0]])
							} else if (self.success.length == 2) {
								resolve(res.data[self.success[0]][self.success[1]])
							} else {
								this._hide()
								this.$emit("error", "接口数据层次太多，无法解析");
								return
							}
						},
						fail: (err) => {
							this._hide()
							this.$emit("error", err);
						}
					})
				})
			}
		}
	}
</script>
<style scoped>
	@import "./style.css";
</style>
